home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 6
/
FM Towns Free Software Collection 6.iso
/
t_os
/
book
/
src
/
menu.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-07-08
|
40KB
|
1,322 lines
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <ctype.h>
#include <egb.h>
#include <mos.h>
#include "event.h"
#include "init.h"
#include "book.h"
#include "cons.h"
#include "keyio.h"
#include "menu.h"
#include "lib.h"
#include "mouse.h"
#define SC STD_COL
#define B1 BOX1_COL
#define B2 BOX2_COL
#define WC WIND_COL
#define BC BTN_COL
#define MEVT_l 128 /* 地の画面の最低メニューレベル */
#define MEVT 131 /* ここで使う最高メニューレベル */
#define Ymin 32 /* 画面の最大位置 */
#define Ymax1 470 /* 画面の最大位置 */
#define Ymax2 450 /* 画面の最大位置 */
#define Xmin 3 /* 画面の最大位置 */
#define Xmax 642 /* 画面の最大位置 */
#define MAX_SW 16
#define LINE_STYLE (0xFF00FF00)
#undef LINE_STYLE
#define LINE_STYLE (0xFFFFFFFF)
/* *** メッセージ・ボックスの定義 *** */
typedef struct {
char *str ; /* ボタンの文字列 */
short x ; /* ボタンの位置 */
short evt ; /* イベント番号 */
} btn_prm ;
typedef struct {
char *str ; /* スイッチの文字列 */
short x, y ; /* スイッチの位置 */
short sw ; /* スイッチの状態 */
short evt ; /* イベント番号 */
} sw_prm ;
typedef struct /* メニューを移動したときの位置情報を渡すための構造体 */
{
short xpos, ypos; /* 開始位置 */
short xsiz, ysiz; /* 大きさ */
mevt_t evt; /* 移動時に発生するイベント */
short ymax; /* Y方向の画面の最大範囲 */
char *ttl; /* タイトル文字列へのポインタ */
short ttly; /* タイトル開始位置 */
short ttllen; /* タイトル文字数 */
btn_prm btn[MAX_BTN_MSG]; /* ボタンの文字列 */
short btny; /* ボタンの位置 */
short btnlen; /* ボタンの文字数 */
short btnnum; /* ボタンの数 */
short btnxsiz, btnysiz; /* ボタンの大きさ */
sw_prm sw[MAX_SW] ; /* スイッチ文字列・位置・大きさ */
short swxsiz, swysiz ; /* スイッチの大きさ */
short swnum ; /* スイッチの数 */
char *msg[MAX_DSP_MSG] ; /* メッセージ文字列 */
short msgx, msgy ; /* メッセージ文字列開始位置 */
short msgpitch ; /* メッセージ表示行ピッチ */
short msgnum, msglen ; /* メッセージ文字列の数と最大文字数 */
void (*func)(int) ; /* 画面再描画ルーチンへのポインタ */
} MENU_PRM ;
static MENU_PRM menu = {0, 0};
static mevt_t menu_event = MEv_NULL;
static int curpos = -1;
int move_menu( int last_x,int last_y, int nx,int ny, int xs,int ys )
{
struct {
short x1,y1, x2,y2;
} para;
short mx = nx - last_x;
short my = ny - last_y;
if (last_x > nx) iswap(&nx, &last_x);
if (last_y > ny) iswap(&ny, &last_y);
para.x1 = last_x, para.y1 = last_y;
para.x2 = nx+xs, para.y2 = ny+ys;
MOS_disp(MOS_OFF);
EGB_color(gwork, 1, 0);
EGB_partScroll(gwork, 1, mx,my, (char *)¶);
MOS_disp(MOS_ON);
return TRUE;
}
int X(x)
{
return ( x % 2 ) ? x : x+1 ;
}
#if 1
static void ROLL_clip( REGS evt_t *ep, int x, int y, int sw )
{
static int s_lx = 0,s_ly = 0, s_mofs_x = 0,s_mofs_y = 0 ;
int lx,ly, mofs_x,mofs_y;
lx = s_lx;
ly = s_ly;
mofs_x = s_mofs_x;
mofs_y = s_mofs_y;
sw = sw;
switch(ep->now)
{
case Ev_CLIP_MOS:
mos_ptn(MOSCSR_HAND);
menu_event = ep->no;
ep->now = Ev_REP_MOS;
ep->x1 = x-menu.xpos+Xmin;
ep->x2 = Xmax-((menu.xpos+menu.xsiz)-x);
ep->y1 = y-menu.ypos+Ymin;
ep->y2 = menu.ymax-((menu.ypos+menu.ysiz)-y);
MOS_horizon (ep->x1, ep->x2);
MOS_vertical(ep->y1, ep->y2);
mofs_x = x - menu.xpos, mofs_y = y - menu.ypos;
lx = X(x - mofs_x), ly = y - mofs_y;
MOS_disp(MOS_OFF);
box(lx+1,ly+1, lx+menu.xsiz-1,ly+menu.ysiz-1, 15,LINE_STYLE,MODE_XOR);
#ifdef MOS_CSR_DISPLAY
MOS_disp(MOS_ON);
#endif
break;
case Ev_REP_MOS:
if (lx != X(x - mofs_x) || ly != y - mofs_y)
{
int llx,lly;
#ifdef MOS_CSR_DISPLAY
MOS_disp(MOS_OFF);
#endif
llx = lx, lly= ly;
lx = X(x - mofs_x), ly = y - mofs_y;
box(lx+1,ly+1, lx+menu.xsiz-1,ly+menu.ysiz-1,
15,LINE_STYLE,MODE_XOR);
box(llx+1,lly+1, llx+menu.xsiz-1,lly+menu.ysiz-1,
15,LINE_STYLE,MODE_XOR);
#ifdef MOS_CSR_DISPLAY
MOS_disp(MOS_ON);
#endif
}
break;
case Ev_DOLACK_MOS:
ep->now = Ev_NON;
case Ev_MOVE_MOS:
case Ev_OFF_MOS:
mos_ptn(MOSCSR_FINGER);
break;
case Ev_SELECT_MOS:
#ifdef MOS_CSR_DISPLAY
MOS_disp(MOS_OFF);
#endif
mos_dispoff(ON);
box(lx+1,ly+1, lx+menu.xsiz-1,ly+menu.ysiz-1, 15,LINE_STYLE,MODE_XOR);
ep->x1 = menu.xpos, ep->x2 = menu.xpos + menu.xsiz;
ep->y1 = menu.ypos, ep->y2 = menu.ypos + menu.ysiz;
menu_event = ep->no;
if (lx != menu.xpos || ly != menu.ypos)
{
move_menu(menu.xpos,menu.ypos, lx,ly, menu.xsiz,menu.ysiz);
menu.xpos = lx; menu.ypos = ly;
menu.func(NO);
}
MOS_horizon (MIN_HORIZON, max_horizon);
MOS_vertical(MIN_VERTICAL, MAX_VERTICAL);
mos_dispoff(OFF);
ep->now = Ev_ON_MOS;
case Ev_ON_MOS:
mos_ptn(MOSCSR_HAND);
MOS_disp(MOS_ON);
break;
}
s_lx = lx;
s_ly = ly;
s_mofs_x = mofs_x;
s_mofs_y = mofs_y;
}
#else
static void ROLL_clip( REGS evt_t *ep, int x, int y, int sw )
{
static int lx = 0,ly = 0, mofs_x = 0,mofs_y = 0 ;
sw = sw;
switch(ep->now)
{
case Ev_CLIP_MOS:
mos_ptn(MOSCSR_HAND);
menu_event = ep->no;
ep->now = Ev_REP_MOS;
ep->x1 = x-menu.xpos+Xmin;
ep->x2 = Xmax-((menu.xpos+menu.xsiz)-x);
ep->y1 = y-menu.ypos+Ymin;
ep->y2 = menu.ymax-((menu.ypos+menu.ysiz)-y);
MOS_horizon (ep->x1, ep->x2);
MOS_vertical(ep->y1, ep->y2);
mofs_x = x - menu.xpos, mofs_y = y - menu.ypos;
lx = X(x - mofs_x), ly = y - mofs_y;
MOS_disp(MOS_OFF);
box(lx+1,ly+1, lx+menu.xsiz-1,ly+menu.ysiz-1, 15,LINE_STYLE,MODE_XOR);
#ifdef MOS_CSR_DISPLAY
MOS_disp(MOS_ON);
#endif
break;
case Ev_REP_MOS:
if (lx != X(x - mofs_x) || ly != y - mofs_y)
{
#ifdef MOS_CSR_DISPLAY
MOS_disp(MOS_OFF);
#endif
box(lx+1,ly+1, lx+menu.xsiz-1,ly+menu.ysiz-1,
15,LINE_STYLE,MODE_XOR);
lx = X(x - mofs_x), ly = y - mofs_y;
box(lx+1,ly+1, lx+menu.xsiz-1,ly+menu.ysiz-1,
15,LINE_STYLE,MODE_XOR);
#ifdef MOS_CSR_DISPLAY
MOS_disp(MOS_ON);
#endif
}
break;
case Ev_DOLACK_MOS:
ep->now = Ev_NON;
case Ev_MOVE_MOS:
case Ev_OFF_MOS:
mos_ptn(MOSCSR_FINGER);
break;
case Ev_SELECT_MOS:
#ifdef MOS_CSR_DISPLAY
MOS_disp(MOS_OFF);
#endif
mos_dispoff(ON);
box(lx+1,ly+1, lx+menu.xsiz-1,ly+menu.ysiz-1, 15,LINE_STYLE,MODE_XOR);
ep->x1 = menu.xpos, ep->x2 = menu.xpos + menu.xsiz;
ep->y1 = menu.ypos, ep->y2 = menu.ypos + menu.ysiz;
menu_event = ep->no;
if (lx != menu.xpos || ly != menu.ypos)
{
move_menu(menu.xpos,menu.ypos, lx,ly, menu.xsiz,menu.ysiz);
menu.xpos = lx; menu.ypos = ly;
menu.func(NO);
}
MOS_horizon (MIN_HORIZON, max_horizon);
MOS_vertical(MIN_VERTICAL, MAX_VERTICAL);
mos_dispoff(OFF);
ep->now = Ev_ON_MOS;
case Ev_ON_MOS:
mos_ptn(MOSCSR_HAND);
MOS_disp(MOS_ON);
break;
}
}
#endif
void DSP_clip_paint(evt_t *ep)
{
MOS_disp(MOS_OFF);
EGB_writeMode(gwork, MODE_XOR);
pbox(ep->x1+1,ep->y1+1, ep->x2-1,ep->y2-1, 2,2);
EGB_writeMode(gwork, MODE_PSET);
MOS_disp(MOS_ON);
}
static void MENU_clip( REGS evt_t *ep, int x, int y, int sw )
{
int now ;
y = y, sw = sw ; /* 意味なし。ワーニングを避けるため */
now = ep->now ;
switch( now )
{
case Ev_CLIP_MOS:
mos_ptn( MOSCSR_HAND ) ;
if( isrepeat( ep ) )
ep->now = Ev_REP_MOS ;
if( !isclip( ep ) )
{
if( ispaint( ep ) )
DSP_clip_paint( ep ) ;
else
DSP_clip_on( ep ) ;
}
break ;
case Ev_REP_MOS: /* リピート動作は特になし */
break ;
case Ev_DOLACK_MOS:
ep->now = Ev_NON ;
case Ev_MOVE_MOS:
if( !isclip( ep ) )
{
if( ispaint( ep ) )
DSP_clip_paint( ep ) ;
else
DSP_clip_off( ep ) ;
}
case Ev_OFF_MOS:
mos_ptn( MOSCSR_FINGER ) ;
break ;
case Ev_SELECT_MOS:
menu_event = ep->no ;
if( iscsr( ep ) )
curpos = (x-ep->x1) / 8 ;
if( !isclip( ep ) )
{
if( ispaint( ep ) )
DSP_clip_paint( ep ) ;
else
DSP_clip_off( ep ) ;
}
ep->now = Ev_ON_MOS ;
case Ev_ON_MOS:
mos_ptn( MOSCSR_HAND ) ;
break ;
}
}
static void RIGHT_click( void )
{
menu_event = MEv_CANCEL ;
}
static void DSP_select_mode( int redraw )
{
auto int i ;
auto int ttlx,ttly, ttlxsiz,ttlysiz ;
auto int xpos,ypos, btnx,btny ;
xpos = menu.xpos ;
ypos = menu.ypos ;
/* 設定 */
mos_ptn( MOSCSR_FINGER ) ;
/* タイトルの位置と大きさ決め */
ttlxsiz = menu.ttllen * 8 + 8 ;
ttlysiz = 22 ;
ttlx = xpos + (menu.xsiz - ttlxsiz) / 2 ;
ttly = ypos + menu.ttly ;
/* ボタンの位置と大きさ決め */
btny = ypos + menu.btny ;
/* 画面作成とイベント登録 */
EVT_level_free( MEVT ) ;
EVT_level_free( MEVT-1 ) ;
/* メニューウィンドゥの表示 */
if( redraw )
{
pbox( xpos, ypos, xpos+menu.xsiz, ypos+menu.ysiz, BAK_COL,BAK_COL);
pbox( xpos+1,ypos+1, xpos+menu.xsiz-1,ypos+menu.ysiz-1, WC,WC ) ;
box2( xpos+3,ypos+3, xpos+menu.xsiz-3,ypos+menu.ysiz-3, B1,B2 ) ;
}
EVT_set_node( xpos,ypos, menu.xsiz,menu.ysiz,
MEVT-1,ROLL_clip,menu.evt, LOCK ) ;
/* タイトル表示 */
if( redraw )
{
box2( ttlx,ttly, ttlx+ttlxsiz,ttly+ttlysiz, B1,B2 ) ;
wrt( menu.ttl,
ttlx+4+(menu.ttllen-strlen(menu.ttl))*4,ttly+3, SC,WC, 16 ) ;
}
/* メッセージ表示 */
if( redraw )
{
for( i = 0 ; i < menu.msgnum ; i ++ )
{
ttlx = (menu.msglen - strlen(menu.msg[i])) * 4;
wrt( menu.msg[i],
xpos+ttlx+4,ypos+16+24+i*menu.msgpitch, SC,WC, 16 ) ;
}
}
/* ボタンの表示とイベント登録 */
for( i = 0 ; i < menu.btnnum ; i ++ )
{
btnx = xpos + menu.btn[i].x ;
if( redraw )
{
dsp_box( btnx,btny, btnx+menu.btnxsiz,btny+menu.btnysiz, B1,B2,BC);
wrt( center(menu.btn[i].str, menu.btnlen), btnx+4,btny+3,SC,BC,16);
}
EVT_set_node( btnx,btny, menu.btnxsiz,menu.btnysiz,
MEVT,MENU_clip,menu.btn[i].evt, NOP ) ;
}
EVT_set_cancel( MEVT, RIGHT_click ) ;
}
/* ボタン・メッセージなどの数と大きさを数える */
/* 戻り値 : str[] に btn[] をコピー、*len に最大文字列長
関数の返り値 : 個数 */
static int count_prm( char *btn[], int max, short *len )
{
int i ;
for( *len = i = 0 ; i < max ; i++ )
{
if( btn[i] == NULL )
break ;
if( strlen( btn[i] ) > *len )
*len = strlen( btn[i] ) ;
}
return i ;
}
int select_mode(char *ttl, char *msg[], char *btn[],
int pitch, int *xcenter, int *ycenter)
{
static int menu_x = 160, menu_y = 210;
int i, ch;
if (xcenter != NULL)
menu_x = *xcenter;
if (ycenter != NULL)
menu_y = *ycenter;
menu.func = DSP_select_mode ;
menu.ymax = Ymax1 ;
pbox(Xmin,Ymin, Xmax,Ymax1, 0,0); /* clear screen */
/* ボタンの数と大きさ */
menu.btnnum = count_prm(btn, MAX_BTN_MSG, &menu.btnlen);
for( i = 0 ; i < menu.btnnum ; i ++ )
menu.btn[i].str = btn[i], menu.btn[i].evt = MEv_MAX + i;
if( menu.btnlen < 8 ) menu.btnlen = 8 ;
else menu.btnlen += menu.btnlen % 2 ;
menu.btnxsiz = menu.btnlen * 8 + 8 ;
menu.btnysiz = 22 ;
/* メッセージの行数と大きさ */
menu.msgnum = count_prm( msg, MAX_DSP_MSG, &menu.msglen ) ;
for (i = 0; i < menu.msgnum; i++)
menu.msg[i] = msg[i];
if (menu.msglen < 30) menu.msglen = 34;
else menu.msglen += (menu.msglen % 2) + 4;
menu.msgpitch = pitch;
/* スイッチの数 */
menu.swnum = 0;
/* ウィンドゥの大きさと位置 */
menu.xsiz = menu.msglen * 8 + 8 ;
menu.ysiz = menu.msgnum * pitch + 20 + 24 + 24 ;
if (menu_x == MENU_CENTERING) { /* X centering */
menu_x = ((Xmax - Xmin) - menu.xsiz) / 2;
}
if (menu_y == MENU_CENTERING) { /* Y centering */
menu_y = ((Ymax1 - Ymin) - menu.ysiz) / 2;
}
if (X((menu.xpos = menu_x) + menu.xsiz) > X(Xmax))
menu.xpos = X(Xmax - menu.xsiz) ;
if (menu.xpos < Xmin)
menu.xpos = Xmin;
if ((menu.ypos = menu_y) + menu.ysiz > menu.ymax)
menu.ypos = menu.ymax - menu.ysiz;
if (menu.ypos < Ymin)
menu.ypos = Ymin;
menu.evt = MEv_NULL;
if( menu.msgnum < 1 || menu.btnnum > MAX_BTN_MSG )
return( FALSE ) ;
/* タイトルの大きさと位置 */
menu.ttl = ttl ;
menu.ttllen = ( strlen( ttl ) > 16 ) ? strlen( ttl ) : 16 ;
menu.ttly = 6 ;
/* ボタンの位置 */
menu.btny = menu.ysiz - 28 ;
switch (menu.btnnum)
{
case 1:
menu.btn[0].x = ( menu.xsiz - menu.btnxsiz ) /2 ;
break ;
case 2:
menu.btn[0].x = menu.xsiz/2 - menu.btnxsiz - 4 ;
menu.btn[1].x = menu.xsiz/2 + 4 ;
break ;
case 3:
menu.btn[1].x = ( menu.xsiz - menu.btnxsiz ) / 2 ;
menu.btn[0].x = menu.btn[1].x - menu.btnxsiz - 8 ;
menu.btn[2].x = menu.btn[1].x + menu.btnxsiz + 8 ;
break ;
}
/* 画面作成 */
MOS_disp(MOS_OFF);
DSP_select_mode(YES);
/* ループの開始 */
MOS_disp(MOS_ON);
while (kb_check() != 0) ; /* キーから手を離すまで待つ */
do {
menu_event = MEv_NULL;
while (menu_event == MEv_NULL && (ch = kb_check()) == 0)
EVT_loop(MEVT_l, MEVT);
if (ch != 0)
{
switch (ch)
{
case 0x01: /* エスケープで中止 */
menu_event = MEv_CANCEL; break;
case 0x73: case 0x1D: case 0x45: /* 改行、実行キーで決定 */
menu_event = MEv_MAX;
}
}
} while (menu_event == MEv_NULL);
MOS_disp(MOS_OFF);
EVT_level_free(MEVT);
pbox(menu.xpos,menu.ypos, menu.xpos+menu.xsiz,menu.ypos+menu.ysiz, 0,0);
MOS_disp(MOS_ON);
menu_x = menu.xpos;
menu_y = menu.ypos;
if (xcenter != NULL)
*xcenter = menu_x;
if (ycenter != NULL)
*ycenter = menu_y;
while (kb_check() != 0) ; /* キーから手を離すまで待つ */
return menu_event == MEv_CANCEL ? -1:(menu_event - MEv_MAX + 1);
}
int select_drive(void)
{
static int menu_x = 160, menu_y = 210;
int ch, drv = -1;
const int pitch = 24;
menu.func = DSP_select_mode;
menu.ymax = Ymax1;
pbox(Xmin,Ymin, Xmax,Ymax1, 0,0); /* clear screen */
/* ボタンの数と大きさ */
menu.btnnum = 1;
menu.btn[0].str = "中 止";
menu.btn[0].evt = MEv_MAX;
menu.btnlen = 8;
menu.btnxsiz = menu.btnlen * 8 + 8;
menu.btnysiz = 22;
/* メッセージの行数と大きさ */
menu.msgnum = 2;
menu.msg[0] = "ドライブ名を入力してください (A-Q)";
menu.msg[1] = "ドライブ名 : _";
menu.msglen = strlen(menu.msg[0]) + 4;
menu.msgpitch = pitch;
/* スイッチの数 */
menu.swnum = 0;
/* ウィンドゥの大きさと位置 */
menu.xsiz = menu.msglen * 8 + 8;
menu.ysiz = menu.msgnum * pitch + 20 + 24 + 24;
if (X((menu.xpos = menu_x) + menu.xsiz) > X(Xmax))
menu.xpos = X(Xmax - menu.xsiz) ;
if (menu.xpos < Xmin)
menu.xpos = Xmin;
if ((menu.ypos = menu_y) + menu.ysiz > menu.ymax)
menu.ypos = menu.ymax - menu.ysiz;
if (menu.ypos < Ymin)
menu.ypos = Ymin;
menu.evt = MEv_NULL;
/* タイトルの大きさと位置 */
menu.ttl = "ドライブ選択";
menu.ttllen = 16;
menu.ttly = 6;
/* ボタンの位置 */
menu.btny = menu.ysiz - 28;
menu.btn[0].x = (menu.xsiz - menu.btnxsiz) / 2;
/* 画面作成 */
MOS_disp(MOS_OFF);
DSP_select_mode(YES);
/* ループの開始 */
MOS_disp(MOS_ON);
while (kb_check() != 0) ; /* キーから手を離すまで待つ */
do {
menu_event = MEv_NULL;
while (menu_event == MEv_NULL && (ch = kb_check()) == 0)
EVT_loop(MEVT_l, MEVT);
if (ch != 0)
{
if (ch == 0x01) /* エスケープで中止 */
menu_event = MEv_CANCEL;
else /* その他のキー入力 */
{
ch = sc_to_char[ch];
if (ch >= 'A' && ch <= 'Z') /* ドライブ名 */
drv = ch - 'A';
}
}
} while (menu_event == MEv_NULL && drv < 0);
MOS_disp(MOS_OFF);
EVT_level_free(MEVT);
pbox(menu.xpos,menu.ypos, menu.xpos+menu.xsiz,menu.ypos+menu.ysiz, 0,0);
MOS_disp(MOS_ON);
menu_x = menu.xpos;
menu_y = menu.ypos;
while (kb_check() != 0) ; /* キーから手を離すまで待つ */
return menu_event == MEv_CANCEL ? -1:drv;
}
static int DSP_rev( int s1, int s2 )
{
void disp( char *str, int x,int y, int fc,int bc )
{
x += menu.xpos, y += menu.ypos ;
dsp_box( x,y, x+menu.swxsiz,y+menu.swysiz, B1,B2, bc ) ;
wrt( str, x+4,y+2, fc,bc, 16 ) ;
}
MOS_disp( MOS_OFF ) ;
disp( menu.sw[s1].str, menu.sw[s1].x,menu.sw[s1].y, SC,WC ) ;
disp( menu.sw[s2].str, menu.sw[s2].x,menu.sw[s2].y, BLACK_l,WHITE_l ) ;
MOS_disp( MOS_ON ) ;
return s2 ;
}
static void DSP_switch( int redraw )
{
short i, x,y, col,bak ;
for( i = 0 ; i < menu.swnum ; i ++ )
{
if( redraw )
{
if( menu.sw[i].sw == TRUE ) col = BLACK_l, bak = WHITE_l ;
else col = SC, bak = WIND_COL ;
x = menu.xpos+menu.sw[i].x, y = menu.ypos+menu.sw[i].y ;
dsp_box( x,y, x+menu.swxsiz,y+menu.swysiz, B1,B2,bak ) ;
wrt( menu.sw[i].str, x+4,y+2, col,bak, 16 ) ;
}
EVT_set_node( menu.xpos+menu.sw[i].x, menu.ypos+menu.sw[i].y,
menu.swxsiz,menu.swysiz, MEVT,MENU_clip,menu.sw[i].evt, NOP ) ;
}
}
static void DSP_select_form( int redraw )
{
DSP_select_mode(redraw);
/* スイッチ表示 */
if (redraw)
{
wrt("改行表示(V)", menu.xpos+16,menu.ypos+42, SC,WC,16);
wrt("制御文字(C)", menu.xpos+16,menu.ypos+42+28, SC,WC,16);
wrt("タブ展開(T)", menu.xpos+16,menu.ypos+42+28*2, SC,WC,16);
wrt("行 間 隔(L)", menu.xpos+16,menu.ypos+42+28*4, SC,WC,16);
}
/* スイッチ表示 */
DSP_switch(redraw);
}
mevt_t select_form(int *disp_cr, int *tab_siz, int *dpl_mode, int *form_ctrl)
{
static int menu_x = 150, menu_y = 60;
int i, ch, cr = 0, tab = 0, dot = 0, ctrl = 0;
#define BX1 120
#define BX2 200
#define BX3 280
cr = *disp_cr ? 0 : 1 ;
dot = *dpl_mode ;
ctrl = *form_ctrl ;
switch( *tab_siz )
{
case 0: tab = 0 ; break ;
case 1: tab = 1 ; break ;
case 4: tab = 2 ; break ;
case 8: tab = 3 ; break ;
}
menu.func = DSP_select_form;
menu.ymax = Ymax1;
/* ウィンドゥの大きさと位置 */
menu.xsiz = 372, menu.ysiz = 216;
if (X((menu.xpos = menu_x) + menu.xsiz) > X(Xmax))
menu.xpos = X(Xmax - menu.xsiz);
if ((menu.ypos = menu_y) + menu.ysiz > menu.ymax)
menu.ypos = menu.ymax - menu.ysiz;
menu.evt = MEv_NULL;
/* タイトル */
menu.ttl = "書式設定";
menu.ttllen = strlen(menu.ttl) + 4;
menu.ttly = 6;
/* スイッチの指定 */
menu.swnum = 11;
menu.sw[0].str = " す る ", menu.sw[0].x = BX1;
menu.sw[1].str = " しない ", menu.sw[1].x = BX2;
menu.sw[0].y = menu.sw[1].y = 40;
menu.sw[2].str = "そのまま", menu.sw[2].x = BX1;
menu.sw[3].str = "整形表示", menu.sw[3].x = BX2;
menu.sw[2].y = menu.sw[3].y = 40+28;
menu.sw[4].str = " しない ", menu.sw[4].x = BX1, menu.sw[4].y = 40+28*2;
menu.sw[5].str = "1カラム", menu.sw[5].x = BX1;
menu.sw[6].str = "4カラム", menu.sw[6].x = BX2;
menu.sw[7].str = "8カラム", menu.sw[7].x = BX3;
menu.sw[5].y = menu.sw[6].y = menu.sw[7].y = 40+28*3;
menu.sw[8].str = "16ドット", menu.sw[8].x = BX1;
menu.sw[9].str = "18ドット", menu.sw[9].x = BX2;
menu.sw[10].str= "20ドット", menu.sw[10].x= BX3;
menu.sw[8].y = menu.sw[9].y = menu.sw[10].y = 40+28*4;
menu.swxsiz = 72, menu.swysiz = 19;
for (i = 0; i < menu.swnum; i++)
menu.sw[i].sw = OFF, menu.sw[i].evt = MEv_MAX + i;
menu.sw[0+cr].sw = menu.sw[2+ctrl].sw =
menu.sw[4+tab].sw = menu.sw[8+dot].sw = ON;
/* ボタンの登録 */
menu.btnnum = 1;
menu.btn[0].evt = MEv_SELECT;
menu.btn[0].str = " 決 定 ";
menu.btnlen = strlen(menu.btn[0].str);
menu.btnxsiz = menu.btnlen * 8 + 8;
menu.btnysiz = 22;
menu.btn[0].x = menu.xsiz/2 - menu.btnxsiz/2;
menu.btny = menu.ysiz - 28;
/* メッセージはなし */
menu.msgnum = 0 ;
/* 画面作成 */
MOS_disp(MOS_OFF);
DSP_select_form(YES);
/* ループの開始 */
MOS_disp(MOS_ON);
while (kb_check() != 0) ; /* キーから手を離すまで待つ */
do {
menu_event = MEv_NULL;
while ((ch = kb_check()) == 0 && menu_event == MEv_NULL)
EVT_loop(MEVT_l, MEVT);
if (ch)
{
switch (ch)
{
case 0x01: case 0x11: /* エスケープ、'Q' で中止 */
menu_event = MEv_CANCEL; break;
case 0x73: case 0x1D: case 0x45: /* 改行、実行キーで決定 */
menu_event = MEv_SELECT;
break;
case 0x2D: /* V で改行選択 */
if ((menu_event = cr + 1) > 1)
menu_event = 0;
menu_event += MEv_MAX;
break;
case 0x2C: /* C で制御文字選択 */
if ((menu_event = ctrl + 1) > 1)
menu_event = 0;
menu_event += MEv_MAX + 2;
break;
case 0x15: /* T でタブ選択 */
if ((menu_event = tab + 1) > 3)
menu_event = 0;
menu_event += MEv_MAX + 4;
break;
case 0x26: /* L で行間隔選択 */
if ((menu_event = dot + 1) > 2)
menu_event = 0;
menu_event += MEv_MAX + 8;
break;
case 0x0B: case 0x46: /* 0 */
menu_event += MEv_MAX + 4; break;
case 0x02: case 0x43: /* 1 */
menu_event += MEv_MAX + 5; break;
case 0x05: case 0x3E: /* 4 */
menu_event += MEv_MAX + 6; break;
case 0x09: case 0x3B: /* 8 */
menu_event += MEv_MAX + 7; break;
}
}
switch (menu_event)
{
case MEv_MAX: case MEv_MAX+1:
if (cr != (menu_event - MEv_MAX))
cr = DSP_rev(cr, menu_event - MEv_MAX) - 0;
break;
case MEv_MAX+2: case MEv_MAX+3:
if (ctrl != (menu_event - (MEv_MAX+2)))
ctrl = DSP_rev(ctrl+2, menu_event - MEv_MAX) - 2;
break;
case (MEv_MAX+4): case (MEv_MAX+5):
case (MEv_MAX+6): case (MEv_MAX+7):
if (tab != (menu_event - (MEv_MAX+4)))
tab = DSP_rev(tab+4, menu_event - MEv_MAX) - 4;
break ;
case (MEv_MAX+8): case (MEv_MAX+9): case (MEv_MAX+10):
if (dot != (menu_event - (MEv_MAX+8)))
dot = DSP_rev(dot+8, menu_event - MEv_MAX) - 8;
break;
}
while (kb_check() != 0) ; /* キーから手を離すまで待つ */
} while (menu_event != MEv_SELECT && menu_event != MEv_CANCEL);
MOS_disp(MOS_OFF);
/* 結果 */
if (menu_event != MEv_CANCEL)
{
*disp_cr = cr == 0 ? TRUE : FALSE ;
*dpl_mode = dot ;
*form_ctrl = ctrl ;
switch (tab)
{
case 0: *tab_siz = 0; break;
case 1: *tab_siz = 1; break;
case 2: *tab_siz = 4; break;
case 3: *tab_siz = 8; break;
}
}
EVT_level_free(MEVT);
pbox(menu.xpos,menu.ypos, menu.xpos+menu.xsiz,menu.ypos+menu.ysiz, 0,0);
MOS_disp(MOS_ON);
menu_x = menu.xpos;
menu_y = menu.ypos;
while (kb_check() != 0) ; /* キーから手を離すまで待つ */
return menu_event;
}
int check_exit(void)
{
static int xc = MENU_CENTERING, yc = MENU_CENTERING;
msg[0] = "終了しますか?" ;
msg[1] = NULL ;
btn[0] = "終 了" ;
btn[1] = "取 消" ;
btn[2] = NULL ;
return select_mode("確 認", msg, btn, 28, &xc,&yc);
}
int select_drag(evt_t *homebtn, int ttlsave,
int x,int y, int xsiz, char *msg[], char *keytbl)
{
int i, ofs, btn_num;
int cancel, ground, ch;
int pos = -1;
char *p;
evt_t *ev[EXCMD_MAX], *ep = NULL;
if (ttlsave)
title_backup(ON); /* タイトル部分の退避 */
MOS_disp(MOS_OFF);
/* 画面作成とイベント登録 */
EVT_level_free(MEVT);
EVT_level_free(MEVT-1);
EVT_set_ground(MEVT-1, RIGHT_click, LEFT);
ground = EVT_control_ground(ON);
EVT_set_cancel(MEVT-1, RIGHT_click);
cancel = EVT_control_cancel(ON);
/* ボタンの表示 */
if ((ep = homebtn) != NULL)
EVT_set_node(ep->x1,ep->y1,ep->x2-ep->x1,ep->y2-ep->y1,
MEVT,MENU_clip,MEv_NULL, CLIP);
ep = NULL;
for (btn_num = i = 0; i < EXCMD_MAX; i++, btn_num++)
{
if (msg[i] == NULL)
break;
if ((ofs = (xsiz - strlen(msg[i])*8 + 1) / 2) < 0)
ofs = 0;
pbox(x,y+i*20, x+xsiz,y+i*20+19, CHR_COL,CHR_COL);
wrt(msg[i], x+ofs,y+i*20+2, BAK_COL,CHR_COL, 16);
ev[i] = EVT_set_node(x,y+i*20, xsiz,19,
MEVT,MENU_clip,MEv_MAX+i, PAINT);
}
/* イベント発生 */
MOS_disp(MOS_ON);
while (kb_check() != 0) ; /* キーから手を離すまで待つ */
do {
menu_event = MEv_NULL;
while (menu_event == MEv_NULL && (ch = kb_check()) == 0)
EVT_loop(MEVT-1, MEVT);
if (menu_event != MEv_NULL && pos >= 0 && ep != NULL)
DSP_clip_paint(ep), ep = NULL, pos = -1;
if (ch)
{
switch (ch)
{
case 0x4D: /* ↑ */
if (ep != NULL)
DSP_clip_paint(ep);
if ((--pos) < 0)
pos = btn_num-1;
DSP_clip_paint(ep = ev[pos]);
break;
case 0x50: /* ↓ */
if (ep != NULL)
DSP_clip_paint(ep);
if ((++pos) >= btn_num)
pos = 0;
DSP_clip_paint(ep = ev[pos]);
break;
case 0x1D: /* 改行、実行キーで決定 */
case 0x45:
case 0x73:
if (pos >= 0)
menu_event = MEv_MAX + pos;
else
menu_event = MEv_NULL;
break;
case 0x01: /* エスケープで中止 */
menu_event = MEv_CANCEL;
break;
default:
if ((p = strchr(keytbl, sc_to_char[ch])) != NULL)
{
menu_event = (p - keytbl) + MEv_MAX;
if (menu_event - MEv_MAX >= btn_num)
menu_event = MEv_NULL;
}
}
while (kb_check() != 0) ; /* キーから手を離すまで待つ */
}
} while (menu_event < MEv_MAX && menu_event != MEv_CANCEL);
MOS_disp(MOS_OFF);
pbox(x,y, x+xsiz,y+btn_num*20+19, 0,0);
MOS_disp(MOS_ON);
EVT_level_free(MEVT);
EVT_level_free(MEVT-1);
EVT_control_ground(ground);
EVT_control_cancel(cancel);
if (ttlsave)
title_backup(OFF); /* タイトル部分の復元 */
while (kb_check() != 0) ; /* キーから手を離すまで待つ */
return menu_event == MEv_CANCEL ? -1:(menu_event - MEv_MAX);
}
static void DSP_input_string(int redraw)
{
int xpos = menu.xpos;
int ypos = menu.ypos;
int msgx = xpos + menu.msgx;
int msgy = ypos + menu.msgy;
int msgxsiz = menu.msglen*8;
wind_close();
DSP_select_mode(redraw);
/* スイッチ表示 */
if (redraw)
{
box2(xpos+menu.sw[1].x-2,ypos+menu.sw[1].y-21,
xpos+menu.sw[0].x+menu.swxsiz+2,ypos+menu.sw[1].y+21, B1,B2);
wrt("英大小文字の区別",
xpos+menu.sw[1].x,ypos+menu.sw[1].y-19,SC,WC, 16);
}
DSP_switch(redraw);
/* 入力行 */
KAN_setposMode(msgx+msgxsiz+8+2-72, msgy+21);
if (redraw)
{
pbox(msgx-3,msgy-2, msgx+msgxsiz+8+1,msgy+15+2, BLACK,BAK_COL);
KAN_dispMode(); /* モード再表示 */
}
EVT_set_node(msgx,msgy, msgxsiz,16, MEVT,MENU_clip,MEv_CURMOVE, CLIP|CSR);
}
static keytbl_t srch_key[] = {
{ 0x24D, MEv_sDOWN}, /* C+↑ : 逆スクロール */
{0xF06E, MEv_sDOWN}, /* 前行 : 逆スクロール */
{ 0x250, MEv_sUP }, /* C+↓ : スクロール */
{0xF070, MEv_sUP }, /* 次行 : スクロール */
{ -1, MEv_NULL }, /* おしまい */
};
mevt_t input_string(char *buf, int only_move,
int *menu_x,int *menu_y, int *size_x,int *size_y,
int *minline, int *maxline)
{
static int last_x = 0, last_y = 0;
static int rewrite = YES;
auto int ch, line_num = -1;
auto int win_close = TRUE, move_start = TRUE;
auto int mos_x, mos_y;
auto mevt_t keyon = MEv_NULL;
const xsiz = 352;
const ysiz = 110;
char *linebuf = NULL;
if (curpos < 0)
curpos = strlen(buf);
linebuf = buf;
menu.func = DSP_input_string;
menu.ymax = Ymax2;
/* ウィンドゥの大きさと位置 */
*size_x = menu.xsiz = xsiz;
*size_y = menu.ysiz = ysiz;
if ((menu.xpos = *menu_x) < Xmin)
menu.xpos = Xmin ;
if (X(menu.xpos + xsiz) > X(Xmax))
menu.xpos = X(Xmax - xsiz);
if ((menu.ypos = *menu_y) < Ymin)
menu.ypos = Ymin;
if (menu.ypos + ysiz > menu.ymax)
menu.ypos = menu.ymax - ysiz;
menu.evt = MEv_MOVE;
/* 移動のみおこなう */
if (only_move)
{
if (move_menu(last_x,last_y, menu.xpos,menu.ypos, xsiz,ysiz))
{
mos_rdpos(NULL, &mos_x,&mos_y);
if (mos_x >= last_x && mos_x <= last_x+xsiz &&
mos_y >= last_y && mos_y <= last_y+ysiz)
MOS_setpos(menu.xpos+mos_x-last_x, menu.ypos+mos_y-last_y);
last_x = *menu_x = menu.xpos;
last_y = *menu_y = menu.ypos;
}
return MEv_CANCEL;
}
/* タイトル */
menu.ttl = "文字列検索";
menu.ttllen = strlen(menu.ttl) + 4;
menu.ttly = 6;
/* ボタン */
menu.btn[0].str = "↑検索", menu.btn[0].x=155;
menu.btn[1].str = "↓検索", menu.btn[1].x=155+64;
menu.btn[2].str = "中 止", menu.btn[2].x=155+128;
menu.btn[0].evt = MEv_rSEARCH;
menu.btn[1].evt = MEv_fSEARCH;
menu.btn[2].evt = MEv_CANCEL;
menu.btny = 80, menu.btnlen = 6, menu.btnnum = 3;
menu.btnxsiz = 58, menu.btnysiz = 22;
/* 入力行の長さ */
menu.msgnum = 0;
menu.msgx = 12, menu.msgy = 36, menu.msglen = 40;
/* スイッチ */
menu.swnum = 2;
menu.sw[0].str = "同一視", menu.sw[0].x = 82;
menu.sw[1].str = "区 別", menu.sw[1].x = 11;
menu.sw[0].evt = MEv_sSAME, menu.sw[1].evt = MEv_sDIFF;
menu.sw[0].y = menu.sw[1].y = 83;
menu.sw[0].sw = menu.sw[1].sw = OFF;
menu.swxsiz = 56 ; menu.swysiz = 19;
menu.sw[setup.caps].sw = ON;
/* 画面作成 */
MOS_disp(MOS_OFF ) ;
DSP_input_string(rewrite);
MOS_disp(MOS_ON);
/* ループの開始 */
keyflush(); /* 先行入力を捨てる */
*minline = *maxline = get_nowline();
/* このループ内で移動した最小/最大行 */
do {
if (win_close)
{
wind_open(menu.xpos+menu.msgx,menu.ypos+menu.msgy,
menu.msglen, &curpos, linebuf);
win_close = FALSE;
}
for (menu_event = MEv_NULL;
menu_event == MEv_NULL && kbhit() == FALSE;
)
{
EVT_loop(MEVT_l, MEVT);
extern short auto_move;
if (keyon != MEv_NULL &&
(auto_move == 0 || keyon != key_event(kb_check(), srch_key)))
{
unset_auto_scroll();
keyon = MEv_NULL;
}
if (line_num != get_nowline())
{
line_num = get_nowline(); /* 画面スクロールでの移動を確認 */
redisp_lnum(); /* 行番号の再表示 */
if (line_num < *minline) *minline = line_num;
if (line_num > *maxline) *maxline = line_num;
}
}
if (kbhit())
{
switch (ch = getch())
{
case 0x101: /* エスケープで中止 */
menu_event = MEv_CANCEL; break;
case 0x173: /* 実行キーは無視 */
case 0x145: /* 改行キー(テンキー側)は無視 */
case 0x11D: /* 改行キーは無視 */
continue;
case 0x14D: /* ↑ */
menu_event = MEv_rSEARCH; break;
case 0x114D: /* SHIFT + ↑ */
menu_event = MEv_ErSEARCH; break;
case 0x16E: /* 前行 */
case 0x214D: /* CTRL + ↑ */
set_auto_scroll(- setup.btn_speed);
keyon = MEv_sDOWN;
break;
case 0x150: /* ↓ */
menu_event = MEv_fSEARCH; break;
case 0x1150: /* SHIFT + ↓ */
menu_event = MEv_FfSEARCH; break;
case 0x170: /* 次行 */
case 0x2150: /* CTRL + ↓ */
set_auto_scroll(setup.btn_speed);
keyon = MEv_sUP;
break;
case 0x214F: /* CTRL + ← [区別] */
menu_event = MEv_sDIFF; break;
case 0x2151: /* CTRL + → [同一視] */
menu_event = MEv_sSAME; break;
default:
inpch(ch); break;
}
}
switch (menu_event)
{
case MEv_MOVE: /* ウィンドゥ移動開始/終了 */
if (move_start)
{
wind_close() ;
MOS_disp(MOS_OFF);
move_start = FALSE ;
break ;
}
else
move_start = TRUE ;
case MEv_CURMOVE: /* カーソル移動 */
win_close = TRUE ;
break ;
case MEv_sSAME: /* 同一視 */
case MEv_sDIFF: /* 区別 */
if (setup.caps != menu_event - MEv_sSAME)
setup.caps = DSP_rev(setup.caps, menu_event - MEv_sSAME);
break ;
}
} while (menu_event != MEv_CANCEL &&
menu_event != MEv_rSEARCH && menu_event != MEv_fSEARCH &&
menu_event != MEv_ErSEARCH && menu_event != MEv_FfSEARCH);
wind_close() ;
MOS_disp( MOS_OFF ) ;
EVT_level_free( MEVT ) ;
if (menu_event == MEv_CANCEL) /* 中止 */
{
pbox( menu.xpos,menu.ypos,
menu.xpos+menu.xsiz,menu.ypos+menu.ysiz, 0,0 ) ;
rewrite = YES ;
}
else
rewrite = NO ;
MOS_disp( MOS_ON ) ;
last_x = *menu_x = menu.xpos ;
last_y = *menu_y = menu.ypos ;
while (kb_check() != 0) ; /* キーから手を離すまで待つ */
return menu_event;
}
void report_fatal_error( err_t type, char *err_msg )
{
static int xc = MENU_CENTERING, yc = MENU_CENTERING;
int mos;
char tmp[80];
mos = get_mos_ptn() ;
DSP_writePage( gwork, 1 ) ;
switch( type )
{
case ERR_FILE: msg[0] = "ファイル読み込み時に問題が発生" ; break ;
case ERR_EXEC: msg[0] = "外部コマンド起動時に問題が発生" ; break ;
}
msg[1] = msg[2] = NULL ;
if( err_msg != NULL )
{
/* sprintf( tmp, "(%s)", err_msg ), msg[1] = tmp ; */
*tmp = '\0' ;
_strcats( 80, tmp, "(", err_msg, ")", NULL ) ;
msg[1] = tmp ;
}
btn[0] = "確 認" ;
btn[1] = NULL ;
select_mode("! WARNING !", msg, btn, 20, &xc,&yc);
set_mos_ptn( mos ) ;
}